<!DOCTYPE HTML>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <link rel="stylesheet" href="../css/monokai-sublime.css">
    <link rel="stylesheet" href="../css/note.css">

    <script src="../js/highlight.pack.js"></script>
    <script src="../js/fixHighLight.js"></script>

    <script>

        hljs.initHighlightingOnLoad();

    </script>

    <title>RecyclerView notifyDataSetChanged不生效排查步骤</title>
</head>
<body onload="replaceCode2ulli();">
<div class="detailTitle">RecyclerView notifyDataSetChanged不生效排查步骤</div>
<div class="detailContent">

    <h3>背景介绍</h3>
    <p>唰唰写完个demo，点击按钮，加载数据并用RecyclerView展示，结果一直是空白。</p>
    <h3>检查RecyclerView自身设置</h3>
    <p>1. 视图xml里RecyclerView的宽高是否正确</p>
    <p>2. 加载成功RecyclerView之后必须设置一个LayoutManager，类型任意设了就行，如下</p>
    <pre><code class="java">
recyclerView.setLayoutManager(new LinearLayoutManager(this));
    </code></pre>
    <p>3. 关联你的recyclerView和对应的RecyclerView.Adapter，如下</p>

    <pre><code class="java">
recyclerView.setAdapter(xxxxxAdapter);
    </code></pre>
    <h3>检查自定义的Adapter</h3>
    <p>1.Adapter只new一次，因为看到许多初学者一出问题就喜欢在数据返回来的时候直接新new一个新的Adapter对象。</p>
    <p>
        2.Adapter在自定义的时候getItemCount需要返回数据集合的大小，刚开始一般情况下返回的是0，于是数据返回来之后，需要Adapter暴露一个传递数据的方法setData，并对那个数据集合进行刷新，用直接赋值的方式即可。网上大量的文章都在说得保留旧的数据集合的引用不变，把新的数据addAll。旧版的recyclerView可能需要倒一遍数据，如：</p>
    <pre><code>
public void setData(List&lt;String&gt; items) {

    //新版的是不是改了？直接赋值就行
    this.items = items;

    //旧版的recyclerView有一些机制，需要像下面一样倒一遍数据
    //this.items.clear();
    //this.items.addAll(items);

    this.notifyDataSetChanged();
}
    </code></pre>
    <p>3.对Adapter设置完数据后，按业务需求调用其notifyDataSetChanged系列方法即可。</p>
    <p>
        4.注意onCreateViewHolder返回的ViewHolder对象的构造方法的入参。一般情况下，此入参是你onCreateViewHolder里LayoutInflater.inflate的结果view，即item布局的根视图，否则你将收到崩溃日志如下：</p>
    <pre><code class="java">
...FATAL EXCEPTION: main

Process: xxxx.demo, PID: 15632
java.lang.IllegalStateException: ViewHolder views must not be attached when created. Ensure that you are not passing 'true' to the attachToRoot parameter of LayoutInflater.inflate(..., boolean attachToRoot)
    at android.support.v7.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:6687)
    at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5869)
    at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5752)

...
</code></pre>


    <p>5.检查item的布局宽高。</p>

    <h3>示例</h3>
    <p><a href="https://gitee.com/cjz010/DemoMVP" target="_parent"> MVP架构下的RecyclerView加载数据并展示 </a></p>
</div>


<div class="note_footer">
    <p><font color=red>&hearts;</font></p>
    <img src="../images/qr.png"></img></div>
</body>
</html>